package com.sbm.shiro;

import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;

import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.apache.shiro.session.mgt.eis.SessionIdGenerator;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;

//@Configuration
public class ShiroConfig {
	private final static String Url_Failed = "/login";
	private final static String Url_Logout = "/logout";
	private final static String Url_Success = "/success";
	private final static String Url_Unautho = "/unautho";

	/** Shiro注解 **/
	@Bean
	public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
		AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
		authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
		return authorizationAttributeSourceAdvisor;
	}

	@Bean
	public SimpleMappingExceptionResolver resolver() {
		SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
		Properties properties = new Properties();
		properties.setProperty(UnauthorizedException.class.getName(), Url_Unautho);
		resolver.setExceptionMappings(properties);
		return resolver;
	}

	/** 访问过滤 **/
	@Bean
	public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
		System.out.println("————初始化Shiro————");
		// 设置SecurityManager
		ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
		shiroFilterFactoryBean.setSecurityManager(securityManager);
		// 跳转页面
		shiroFilterFactoryBean.setLoginUrl(Url_Failed);
		shiroFilterFactoryBean.setSuccessUrl(Url_Success);
		shiroFilterFactoryBean.setUnauthorizedUrl(Url_Unautho);
		// 拦截器
		Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
		filterChainDefinitionMap.put(Url_Logout, "logout");
		filterChainDefinitionMap.put("/**", "authc");
		shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
		return shiroFilterFactoryBean;
	}

	/** Web安全管理器 **/
	@Bean
	public SecurityManager getDefaultWebSecurityManager() {
		DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
		securityManager.setRealm(shiroRealm());
		securityManager.setSessionManager(defaultWebSessionManager());
		return securityManager;
	}

	/** 权限管理 **/
	@Bean
	public ShiroRealm shiroRealm() {
		ShiroRealm realm = new ShiroRealm();
		realm.setCacheManager(cacheManager());
		// realm.setCredentialsMatcher(hashedCredentialsMatcher());
		return realm;
	}

	/** 登录缓存 **/
	@Bean
	public EhCacheManager cacheManager() {
		EhCacheManager cacheManager = new EhCacheManager();
		cacheManager.setCacheManagerConfigFile("classpath:ehcache.xml");
		return cacheManager;
	}

	@Bean
	public DefaultWebSessionManager defaultWebSessionManager() {
		ShiroSessionManager sessionManager = new ShiroSessionManager();
		sessionManager.setGlobalSessionTimeout(60000);
		sessionManager.setDeleteInvalidSessions(true);
		sessionManager.setSessionValidationSchedulerEnabled(false);
		sessionManager.setSessionDAO(enterpriseCacheSessionDAO());
		return sessionManager;
	}

	@Bean
	public EnterpriseCacheSessionDAO enterpriseCacheSessionDAO() {
		EnterpriseCacheSessionDAO dao = new EnterpriseCacheSessionDAO();
		dao.setSessionIdGenerator(sessionIdGenerator());
		dao.setActiveSessionsCache(sessionCache());
		return dao;
	}

	@Bean
	public SessionIdGenerator sessionIdGenerator() {
		return new ShiroSessionIdGenerator();
	}

	@Bean
	public Cache<Serializable, Session> sessionCache() {
		return new ShiroSessionCache();
	}
}
